#include <sstream>
#include "httpprot_defs.h"
#include "httpprot_response.h"


namespace httpprot
{
	void Response::updateContentLength( )
	{
		std::pair< std::map< std::string, std::string >::iterator, bool > p = m_headers.insert( std::pair< std::string, std::string >( "Content-Length", "" ) );
		std::map< std::string, std::string >::iterator it = p.first;

		std::ostringstream stream;
		stream << m_message.size( );

		(*it).second = stream.str( );
	}

	void Response::storeChar( char c, std::vector< char >& bufferOut )
	{
		bufferOut.push_back( c );
	}

	void Response::storeCString( const char * cString, std::vector< char >& bufferOut )
	{
		unsigned int length = strlen( cString );
		bufferOut.insert( bufferOut.end( ), cString, cString + length );
	}

	void Response::storeString( const std::string& s, std::vector< char >& bufferOut )
	{
		unsigned int length = s.length( );
		if( length )
		{
			const char * cString = s.c_str( );
			bufferOut.insert( bufferOut.end( ), cString, cString + length );
		}
	}

	void Response::storeVector( const std::vector< char >& v, std::vector< char >& bufferOut )
	{
		bufferOut.insert( bufferOut.end( ), v.begin( ), v.end( ) );
	}

	void Response::ToBuffer( std::vector< char >& bufferOut )
	{
		updateContentLength( );

		// Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
		storeCString( "HTTP/1.1", bufferOut );
		storeChar( SP, bufferOut );
		storeCString( GetStatusCodeString( m_status ), bufferOut );
		storeChar( SP, bufferOut );
		storeCString( GetStatusReasonString( m_status ), bufferOut );
		storeChar( CR, bufferOut );
		storeChar( LF, bufferOut );

		for( std::map< std::string, std::string >::iterator end = m_headers.end( ),
			 it = m_headers.begin( ); it != end; ++it )
		{
			// Header = Name: SP Value CRLF
			storeString( (*it).first, bufferOut );
			storeChar( ':', bufferOut );
			storeChar( SP, bufferOut );
			storeString( (*it).second, bufferOut );
			storeChar( CR, bufferOut );
			storeChar( LF, bufferOut );
		}

		// CRLF
		storeChar( CR, bufferOut );
		storeChar( LF, bufferOut );

		// message
		storeVector( m_message, bufferOut );
	}
};